#include "Configuration.hpp"
#include "eeprom_device.hpp"

#include "stdio.h"

SystemConfiguration default_system_configuration = {
    .motor_position = 0.5,
    .motor_position_minimum = 0.0,
    .motor_position_maximum = 1.0,
    .motor_motion_margin = 0.02,
    .device_serial_number = {
        'C','Z','-','M','D','2','4','1','0',
    },
    .device_password = {
        0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
    },
    .firmware_version = {
        1,0,0,3
    },
    .motor_minlength_voltage = 0,
    .motor_maxlength_voltage = 0,
    .chip_id = {*(volatile uint32_t *)(0X1FFFF7E8),*(volatile uint32_t *)(0X1FFFF7EC),*(volatile uint32_t *)(0X1FFFF7E8)},
    .inputduty_switch = 0,
    .position_switch = 0,
    .calibration_switch = 0,
    .bluetooth_switch = 1,
};

MotionCharacteristicData default_motion_characteristic_data = {
    .n_data_points = 11,
    .x_data = {
    0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0
    },
    .y_data = {
    0,0.11,0.21,0.31,0.4,0.53,0.62,0.77,0.82,0.94,1.0
    },
    .system_initialized = 0xe1,
};

extern SystemConfiguration system_configuration;
extern MotionCharacteristicData system_motion_characteristic_data;

static const unsigned int system_configuration_address = 0x0000;
static const unsigned int system_motion_characteristic_data_address = 0x0000 + sizeof(SystemConfiguration);

bool Configurator::load(){
    EEPROM *eeprom = getEEPROM();
    eeprom->open();
    eeprom->read(&system_configuration,system_configuration_address,sizeof(SystemConfiguration));
    eeprom->read(&system_motion_characteristic_data,system_motion_characteristic_data_address,sizeof(MotionCharacteristicData));
    if ( system_motion_characteristic_data.system_initialized != 0xe1 ){
        printf("system_configuration.system_initialized != 0xe1\r\n");
        system_configuration = default_system_configuration;
        system_motion_characteristic_data = default_motion_characteristic_data;
        eeprom->write(&system_configuration,system_configuration_address,sizeof(SystemConfiguration));
        eeprom->write(&system_motion_characteristic_data,system_motion_characteristic_data_address,sizeof(MotionCharacteristicData));
    }
    else printf("system_configuration.system_initialized == 0xe1\r\n");    
    eeprom->close();
    return true;
}

bool Configurator::sync(){
    EEPROM *eeprom = getEEPROM();
    eeprom->open();
    if ( eeprom == nullptr ) return false;
    eeprom->write(&system_configuration,system_configuration_address,sizeof(SystemConfiguration));
    eeprom->write(&system_motion_characteristic_data,system_motion_characteristic_data_address,sizeof(MotionCharacteristicData));

    eeprom->close();
    return true;
}


bool init_load(){
    uint32_t offset = 0x00000000;
    EEPROM *eeprom = getEEPROM();
    offset = (unsigned int)(&system_motion_characteristic_data.system_initialized) - (unsigned int)(&system_motion_characteristic_data);
    eeprom->open();
    eeprom->read(&system_motion_characteristic_data.system_initialized,0x0000 + sizeof(SystemConfiguration) + offset,sizeof(default_motion_characteristic_data.system_initialized));

    if ( system_motion_characteristic_data.system_initialized != 0xe1 ){
        printf("default_motion_characteristic_data.system_initialized != 0xe1 \r\n");
        system_configuration = default_system_configuration;
        system_motion_characteristic_data = default_motion_characteristic_data;
        eeprom->write(&system_configuration,0x0000,sizeof(SystemConfiguration));
        eeprom->write(&system_motion_characteristic_data,0x0000 + sizeof(SystemConfiguration),sizeof(MotionCharacteristicData));
    }
    else {
        printf("default_motion_characteristic_data.system_initialized == 0xe1 \r\n "); 
    } 
    /* 读取全部信息 */
    eeprom->read(&system_configuration,system_configuration_address,sizeof(SystemConfiguration));
    eeprom->read(&system_motion_characteristic_data,system_motion_characteristic_data_address,sizeof(MotionCharacteristicData));
    return true;
}

bool init_sync(){
    uint32_t offset = 0x00000000;
    EEPROM *eeprom = getEEPROM();
    eeprom->open();
    system_configuration = {0};
    system_motion_characteristic_data = {0};
    offset = offset = (unsigned int)(&system_motion_characteristic_data.system_initialized) - (unsigned int)(&system_motion_characteristic_data);
    
    eeprom->write(&(system_motion_characteristic_data.system_initialized),0x0000 + sizeof(system_configuration) + offset,sizeof(system_motion_characteristic_data.system_initialized));  
    eeprom->close();

    return true;
}